import axios from 'axios'
import md5 from 'md5'
import { Message, Notification, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { reject, resolve } from 'core-js/fn/promise'

const cacheResult = {}
let requestQueue = []

let loadingInstance = null
let loadingcount = 0
let loadingInstanceArr = []

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 15000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent
    console.log('config 2::', config)
    console.log('key2::', getKey(config))
    loadingcount += 1
    loadingInstance = Loading.service({ target: 'body', spinner: 'el-icon-loading', customClass: 'app-loading', background: 'rgba(0, 0, 0, 0.1)' })
    loadingInstanceArr.push(loadingInstance)

    if (store.getters.token) {
      config.headers['Authorization'] = getToken()
    }
    return config
  },
  error => {
    // 重置请求队列
    requestQueue = []
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(

  response => {
    // 获取 请求的签名
    const key = getKey(response.config)
    console.log('config 3::', response.config)
    console.log('key3:', key)
    loadingcount -= 1
    if (!loadingcount) {
      // loadingInstance.close()
      loadingInstanceArr.forEach((item) => {
        item.close()
      })
      loadingInstanceArr = []
    }

    const res = response.data // 数据库 返回的数据
    if (res.meta.status >= 400) {
      Notification({
        type: 'error',
        title: '错误信息',
        message: res.meta.msg
      })
      return Promise.reject(res.meta)
    }
    // 缓存请求数据
    if(cacheResult.hasOwnProperty(key)){
      cacheResult[key] = {
        data: res.hasOwnProperty('data') ? res.data : res,
        timestamp: new Date().getTime()
      }
    }
    // 从请求队列中移除
    const index = requestQueue.findIndex(i => i === key)
    if (index !== -1) {
      requestQueue.splice(index, 1)
    }
    return res.data
  },
  error => {
    // 重置请求队列
    requestQueue = []
    loadingcount -= 1
    if (!loadingcount) loadingInstance.close()
    console.log('error::', error)
    Notification({
      type: 'error',
      title: '错误信息',
      message: error.message
    })
    return Promise.reject(error)
  }
)

/**
 *
 * @param {config}  请求配置信息
 * @return {*}      请求签名加密后字符串
 */
function getKey(config) {
  const data = JSON.parse(JSON.stringify(config))
  if(!data.url.startsWith(process.env.VUE_APP_BASE_API)){
    if(process.env.VUE_APP_BASE_API.endsWith('/') && data.url.startsWith('/')){
      data.url = data.url.slice(1)
    }
    data.url = process.env.VUE_APP_BASE_API + data.url
  }
  if(!data.data){
    data.data = {}
  }
  if(!data.params){
    data.params = {}
  }
  
  data.method = data.method.toLocaleLowerCase()
  data.url = data.url.toLocaleLowerCase()
  try {
    data.data = typeof data.data === 'string'? JSON.stringify(JSON.parse(data.data)) : JSON.stringify(data.data)

  } catch(err) {
    console.log('err:', err)
  }
  try {
    data.params = typeof data.params === 'string'? JSON.stringify(JSON.parse(data.params)): JSON.stringify(data.params)
  } catch(err){
    console.log('err:', err)
  }
  return md5(data.method + data.url + data.data + data.params)
}

/**
 * 判断缓存是否有效
 * @param {timestamp}  缓存结果的时间戳
 * @param {interval}   缓存有效时间
 * @return {*}         true: 过期失效     false: 有效
 */

function isExpires(timestamp, interval = 60 * 60) {
  const now = new Date().getTime()
  return now > timestamp + interval * 1000
}

/**
 * 缓存及去重复请求
 */
function http(config) {
  console.log('config 1::', config)
  console.log('cacheResult', cacheResult)
  const key = getKey(config)
  console.log('key1:', key)
  if(config.cache){
    if(cacheResult.hasOwnProperty(key) && cacheResult[key] && !isExpires(cacheResult[key].timestamp)) {
      return new Promise((resolve, reject)=>{
        resolve((cacheResult[key].data))
      })
    } else {
      cacheResult[key] = null
    }
  }
  if(requestQueue.includes(key)){
    return
  }
  requestQueue.push(key)
  return service(config)
}

export default http
